package com.raising.framework.shiro.realm;

import com.raising.utils.JCacheUtils;
import com.raising.utils.PasswordUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 自定义验证比较类,核心类
 * @author gaoy
 * 2017 2017-5-8 下午8:19:19
 */
public class MyCredentialsMatcher extends SimpleCredentialsMatcher {

	private static final Logger logger = LoggerFactory.getLogger(MyCredentialsMatcher.class);

	/**
	 * 比较器，比较当前账号密码是否正确
	 * 错误次数统计拦截
	 * @author gaoy
	 */
	@Override
    public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) {
		if(logger.isDebugEnabled()){
			logger.debug("【Shiro】>>> MyCredentialsMatcher.doCredentialsMatch()，比较器进行比较账号密码");
		}
		String username = (String)authcToken.getPrincipal();
        //错误次数累加 10分钟后清除
        Integer retryCount = (Integer) JCacheUtils.get(JCacheUtils.PWD_RETRY_CACHE,username);
        if(retryCount == null) {
        	retryCount = 0;
        }
        //这里设置成错误20次
        if(retryCount > 20) {
            //规定时间内超出错误次数
            throw new ExcessiveAttemptsException();
        }
        //调用父类匹配方案 GY
        boolean matches = doCredentialsMatchCustom(authcToken, info);
        if(matches) {
            //匹配正确后，清除错误计数器
			JCacheUtils.remove(JCacheUtils.PWD_RETRY_CACHE,username);
        }else{
        	retryCount++;
			JCacheUtils.put(JCacheUtils.PWD_RETRY_CACHE,username, retryCount);
        }
        return matches;
    }

	/**
	 * 登录校验
	 * @author gaoy
	 * 2017 2017-6-19 下午5:49:30
	 * @param authcToken 存储的是登录信息
	 * @param authcInfo 存储的是 MyUserRealm.doGetAuthenticationInfo() 中的认证信息
	 * @return
	 */
	public boolean doCredentialsMatchCustom(AuthenticationToken authcToken,AuthenticationInfo authcInfo){
		MyUsernamePasswordToken token = (MyUsernamePasswordToken) authcToken;
		/** 表单 */
		// 账号
		String username = token.getUsername();
		// 密码
		String inputPassword = new String(token.getPassword());

		/** 数据库中数据 */
		SimpleAuthenticationInfo simpleAuthcInfo = (SimpleAuthenticationInfo)authcInfo;
		// 加密盐
		ByteSource salt = simpleAuthcInfo.getCredentialsSalt();
		// 密码
		String realPassword = (String)simpleAuthcInfo.getCredentials();

		//自定义判断
		PasswordUtils passwordHelper = new PasswordUtils();
		//将密码加密与系统加密后的密码校验，内容一致就返回true,不一致就返回false
		if(equals(passwordHelper.getPassword(inputPassword, salt), realPassword)){
			if(logger.isDebugEnabled()){
				logger.debug("【Shiro】>>> MyCredentialsMatcher.doCredentialsMatch()，账号密码正确");
			}
			return true;
		}else{
			if(logger.isDebugEnabled()){
				logger.debug("【Shiro】>>> MyCredentialsMatcher.doCredentialsMatch()，账号密码不匹配");
			}
			return false;
		}
	}

}
